home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 7 / Amiga Format AFCD07 (Dec 1996, Issue 91).iso / serious / shareware / programming / aros / intuition / refreshglist.c < prev    next >
C/C++ Source or Header  |  1996-09-12  |  11KB  |  519 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: refreshglist.c,v 1.3 1996/08/29 13:57:38 digulla Exp $
  4.     $Log: refreshglist.c,v $
  5.     Revision 1.3  1996/08/29 13:57:38  digulla
  6.     Commented
  7.     Moved common code from driver to Intuition
  8.  
  9.     Revision 1.2  1996/08/29 07:50:49  digulla
  10.     Fixed a small bug in PropGadgets. The jumpsize of the knob was too small.
  11.  
  12.     Revision 1.1  1996/08/28 17:55:36  digulla
  13.     Proportional gadgets
  14.     BOOPSI
  15.  
  16.  
  17.     Desc:
  18.     Lang: english
  19. */
  20. #include <clib/graphics_protos.h>
  21. #include "intuition_intern.h"
  22.  
  23. int CalcKnobSize (struct Gadget * propGadget, long * knobleft, long * knobtop,
  24.     long * knobwidth, long * knobheight)
  25. {
  26.     struct PropInfo * pi;
  27.  
  28.     pi = (struct PropInfo *)propGadget->SpecialInfo;
  29.  
  30.     if (pi->Flags & PROPBORDERLESS)
  31.     {
  32.     pi->LeftBorder = 0;
  33.     pi->TopBorder  = 0;
  34.     }
  35.     else
  36.     {
  37.     *knobleft += 3;
  38.     *knobtop += 3;
  39.     *knobwidth -= 6;
  40.     *knobheight -= 6;
  41.     pi->LeftBorder = 3;
  42.     pi->TopBorder  = 3;
  43.     }
  44.  
  45.     pi->CWidth       = *knobwidth;
  46.     pi->CHeight    = *knobheight;
  47.  
  48.     if (*knobwidth < KNOBHMIN || *knobheight < KNOBVMIN)
  49.     return FALSE;
  50.  
  51.     if (pi->Flags & FREEHORIZ)
  52.     {
  53.     *knobwidth = pi->CWidth * pi->HorizBody / MAXBODY;
  54.  
  55.     *knobleft = *knobleft + (pi->CWidth - *knobwidth)
  56.         * pi->HorizPot / MAXPOT;
  57.  
  58.     if (pi->HorizBody)
  59.     {
  60.         if (pi->HorizBody < MAXBODY/2)
  61.         pi->HPotRes = MAXPOT / ((MAXBODY / pi->HorizBody) - 1);
  62.         else
  63.         pi->HPotRes = MAXPOT;
  64.     }
  65.     else
  66.         pi->HPotRes = 1;
  67.     }
  68.  
  69.     if (pi->Flags & FREEVERT)
  70.     {
  71.     *knobheight = pi->CHeight * pi->VertBody / MAXBODY;
  72.  
  73.     *knobtop = *knobtop + (pi->CHeight - *knobheight)
  74.         * pi->VertPot / MAXPOT;
  75.  
  76.     if (pi->VertBody)
  77.     {
  78.         if (pi->VertBody < MAXBODY/2)
  79.         pi->VPotRes = MAXPOT / ((MAXBODY / pi->VertBody) - 1);
  80.         else
  81.         pi->VPotRes = MAXPOT;
  82.     }
  83.     else
  84.         pi->VPotRes = 1;
  85.     }
  86.  
  87.     return TRUE;
  88. }
  89.  
  90. /*****************************************************************************
  91.  
  92.     NAME */
  93.     #include <clib/intuition_protos.h>
  94.  
  95.     __AROS_LH4(void, RefreshGList,
  96.  
  97. /*  SYNOPSIS */
  98.     __AROS_LHA(struct Gadget    *, gadgets, A0),
  99.     __AROS_LHA(struct Window    *, window, A1),
  100.     __AROS_LHA(struct Requester *, requester, A2),
  101.     __AROS_LHA(long              , numGad, D0),
  102.  
  103. /*  LOCATION */
  104.     struct IntuitionBase *, IntuitionBase, 72, Intuition)
  105.  
  106. /*  FUNCTION
  107.     Refresh (draw anew) the specified number of gadgets starting
  108.     at the specified gadget.
  109.  
  110.     INPUTS
  111.     gadgets - This is the first gadget which will be refreshed.
  112.     window - The window which contains the gadget
  113.     requester - If the gadget has GTYP_REQGADGET set, this must be
  114.         a pointer to a Requester; otherwise the value is
  115.         ignored.
  116.     numGad - How many gadgets should be refreshed. The value
  117.         may range from 0 to MAXLONG. If there are less gadgets
  118.         in the list than numGad, only the gadgets in the
  119.         list will be refreshed.
  120.  
  121.     RESULT
  122.     None.
  123.  
  124.     NOTES
  125.     This function *must not* be called inside a
  126.     BeginRefresh()/EndRefresh() pair.
  127.  
  128.     EXAMPLE
  129.     // Refresh one gadget
  130.     RefreshGList (&gadget, win, NULL, 1);
  131.  
  132.     // Refresh all gadgets in the window
  133.     RefreshGList (win->FirstGadget, win, NULL, -1L);
  134.  
  135.     BUGS
  136.  
  137.     SEE ALSO
  138.  
  139.     INTERNALS
  140.  
  141.     HISTORY
  142.     29-10-95    digulla automatically created from
  143.                 intuition_lib.fd and clib/intuition_protos.h
  144.  
  145. *****************************************************************************/
  146. {
  147.     __AROS_FUNC_INIT
  148.     __AROS_BASE_EXT_DECL(struct IntuitionBase *,IntuitionBase)
  149.  
  150.     APTR render;
  151.     WORD left, top, width, height;
  152.     UBYTE DrawMode;
  153.     ULONG apen;
  154.  
  155. #define ADDREL(flag,field)  ((gadgets->Flags & (flag)) ? window->field : 0)
  156. #define RENDERGADGET(win,gad,rend)              \
  157.     if (rend)                               \
  158.     {                    \
  159.         if (gad->Flags & GFLG_GADGIMAGE)    \
  160.         {                    \
  161.         DrawImage (win->RPort           \
  162.             , (struct Image *)rend      \
  163.             , left            \
  164.             , top            \
  165.         );                \
  166.         }                    \
  167.         else                \
  168.         {                    \
  169.         DrawBorder (win->RPort          \
  170.             , (struct Border *)rend     \
  171.             , left            \
  172.             , top            \
  173.         );                \
  174.         }                    \
  175.     }
  176. #define GETRENDER(gad)  (gad->Flags & GFLG_SELECTED) ? \
  177.                 gad->SelectRender : gad->GadgetRender;
  178.  
  179.     apen = GetAPen (window->RPort);
  180.     DrawMode = GetDrMd (window->RPort);
  181.  
  182.     for ( ; gadgets && numGad; gadgets=gadgets->NextGadget, numGad --)
  183.     {
  184.     left   = ADDREL(GFLG_RELRIGHT,Width)   + gadgets->LeftEdge;
  185.     top    = ADDREL(GFLG_RELBOTTOM,Height) + gadgets->TopEdge;
  186.     width  = ADDREL(GFLG_RELWIDTH,Width)   + gadgets->Width;
  187.     height = ADDREL(GFLG_RELHEIGHT,Height) + gadgets->Height;
  188.  
  189.     if (width <= 0 || height <= 0)
  190.         continue;
  191.  
  192.     SetDrMd (window->RPort, JAM1);
  193.     SetAPen (window->RPort, 0);
  194.  
  195.     RectFill (window->RPort
  196.         , left
  197.         , top
  198.         , left + width - 1
  199.         , top + height - 1
  200.     );
  201.  
  202.     switch (gadgets->GadgetType & GTYP_GTYPEMASK)
  203.     {
  204.     case GTYP_BOOLGADGET:
  205.         if (gadgets->GadgetText)
  206.         {
  207.         switch (gadgets->Flags & GFLG_LABELMASK)
  208.         {
  209.         case GFLG_LABELITEXT:
  210.             PrintIText (window->RPort
  211.             , gadgets->GadgetText
  212.             , left
  213.             , top
  214.             );
  215.             break;
  216.  
  217.         case GFLG_LABELSTRING: {
  218.             STRPTR text = (STRPTR) gadgets->GadgetText;
  219.             int len, labelwidth, labelheight;
  220.  
  221.             len = strlen (text);
  222.  
  223.             labelwidth = TextLength (window->RPort, text, len);
  224.             labelheight = window->RPort->Font->tf_YSize;
  225.  
  226.             SetAPen (window->RPort, 1);
  227.             SetDrMd (window->RPort, JAM1);
  228.  
  229.             Move (window->RPort
  230.             , left + width/2 - labelwidth/2
  231.             , top + height/2 - labelheight/2
  232.                 + window->RPort->Font->tf_Baseline
  233.             );
  234.             Text (window->RPort, text, len);
  235.  
  236.             break; }
  237.  
  238.         case GFLG_LABELIMAGE:
  239.             DrawImage (window->RPort
  240.             , (struct Image *)gadgets->GadgetText
  241.             , left
  242.             , top
  243.             );
  244.             break;
  245.         }
  246.         }
  247.         switch (gadgets->Flags & GFLG_GADGHIGHBITS)
  248.         {
  249.         case GFLG_GADGHCOMP: {
  250.         render = gadgets->GadgetRender;
  251.         RENDERGADGET(window,gadgets,render);
  252.  
  253.         if (gadgets->Flags & GFLG_SELECTED)
  254.         {
  255.             SetDrMd (window->RPort, COMPLEMENT);
  256.  
  257.             RectFill (window->RPort
  258.             , left
  259.             , top
  260.             , left + width - 1
  261.             , top + height - 1
  262.             );
  263.         }
  264.  
  265.         break; }
  266.  
  267.         case GFLG_GADGHIMAGE:
  268.         render = GETRENDER(gadgets);
  269.         RENDERGADGET(window,gadgets,render);
  270.         break;
  271.  
  272.         case GFLG_GADGHNONE:
  273.         render = gadgets->GadgetRender;
  274.         RENDERGADGET(window,gadgets,render);
  275.         break;
  276.  
  277.         case GFLG_GADGHBOX:
  278.         render = gadgets->GadgetRender;
  279.         RENDERGADGET(window,gadgets,render);
  280.  
  281.         if (gadgets->Flags & GFLG_SELECTED)
  282.         {
  283.             SetDrMd (window->RPort, COMPLEMENT);
  284.  
  285.     #define BOXWIDTH 5
  286.             RectFill (window->RPort
  287.             , left
  288.             , top
  289.             , left + width - 1
  290.             , top + height - 1
  291.             );
  292.  
  293.             if (width > 2*BOXWIDTH && height > 2*BOXWIDTH)
  294.             {
  295.             RectFill (window->RPort
  296.                 , left + BOXWIDTH
  297.                 , top + BOXWIDTH
  298.                 , left + width - BOXWIDTH - 1
  299.                 , top + height - BOXWIDTH - 1
  300.             );
  301.             }
  302.         }
  303.  
  304.         break;
  305.  
  306.         } /* switch GadgetHighlightMethod */
  307.  
  308.         break; /* BOOLGADGET */
  309.  
  310.     case GTYP_GADGET0002:
  311.         break;
  312.  
  313.     case GTYP_PROPGADGET: {
  314.         long knobleft, knobtop;
  315.         long knobwidth, knobheight;
  316.         struct PropInfo * pi;
  317.  
  318.         SetDrMd (window->RPort, JAM1);
  319.  
  320.         pi = (struct PropInfo *)gadgets->SpecialInfo;
  321.  
  322.         if (!pi)
  323.         break;
  324.  
  325.         knobleft = left;
  326.         knobtop = top;
  327.         knobwidth = width;
  328.         knobheight = height;
  329.  
  330.         if (!CalcKnobSize (gadgets, &knobleft, &knobtop, &knobwidth, &knobheight))
  331.         break;
  332.  
  333.         if (!(pi->Flags & PROPBORDERLESS) )
  334.         {
  335.         if (pi->Flags & PROPNEWLOOK)
  336.         {
  337.             if (width <= 6 || height <= 6)
  338.             {
  339.             SetAPen (window->RPort, 2);
  340.  
  341.             RectFill (window->RPort
  342.                 , left
  343.                 , top
  344.                 , left + width - 1
  345.                 , top + height - 1
  346.             );
  347.  
  348.             break;
  349.             }
  350.             else
  351.             {
  352.             SetAPen (window->RPort, 2);
  353.  
  354.             /* right */
  355.             RectFill (window->RPort
  356.                 , left + width - 2
  357.                 , top
  358.                 , left + width - 1
  359.                 , top + height - 1
  360.             );
  361.  
  362.             /* bottom */
  363.             RectFill (window->RPort
  364.                 , left
  365.                 , top + height - 2
  366.                 , left + width - 3
  367.                 , top + height - 1
  368.             );
  369.  
  370.             SetAPen (window->RPort, 1);
  371.  
  372.             /* top */
  373.             RectFill (window->RPort
  374.                 , left
  375.                 , top
  376.                 , left + width - 2
  377.                 , top + 1
  378.             );
  379.  
  380.             /* left */
  381.             RectFill (window->RPort
  382.                 , left
  383.                 , top
  384.                 , left + 1
  385.                 , top + height - 2
  386.             );
  387.  
  388.             WritePixel (window->RPort, left + width - 1, top);
  389.             WritePixel (window->RPort, left, top + height - 1);
  390.             }
  391.         }
  392.         else
  393.         {
  394.             SetAPen (window->RPort, 2);
  395.  
  396.             if (width <= 6 || height <= 6)
  397.             {
  398.             RectFill (window->RPort
  399.                 , left
  400.                 , top
  401.                 , left + width - 1
  402.                 , top + height - 1
  403.             );
  404.  
  405.             break;
  406.             }
  407.             else
  408.             {
  409.             /* right */
  410.             RectFill (window->RPort
  411.                 , left + width - 2
  412.                 , top
  413.                 , left + width - 1
  414.                 , top + height - 1
  415.             );
  416.  
  417.             /* bottom */
  418.             RectFill (window->RPort
  419.                 , left
  420.                 , top + height - 2
  421.                 , left + width - 1
  422.                 , top + height - 1
  423.             );
  424.  
  425.             /* top */
  426.             RectFill (window->RPort
  427.                 , left
  428.                 , top
  429.                 , left + width - 3
  430.                 , top + 1
  431.             );
  432.  
  433.             /* left */
  434.             RectFill (window->RPort
  435.                 , left
  436.                 , top
  437.                 , left + 1
  438.                 , top + height - 3
  439.             );
  440.             }
  441.         }
  442.         }
  443.  
  444.         if (pi->Flags & AUTOKNOB)
  445.         {
  446.         int hit = ((pi->Flags & KNOBHIT) != 0);
  447.  
  448.         if (pi->Flags & PROPNEWLOOK)
  449.         {
  450.             SetAPen (window->RPort, hit ? 2 : 1);
  451.  
  452.             /* Draw right border */
  453.             RectFill (window->RPort
  454.             , knobleft + knobwidth - 2
  455.             , knobtop
  456.             , knobleft + knobwidth - 1
  457.             , knobtop + knobheight - 1
  458.             );
  459.  
  460.             /* Draw bottom border */
  461.             RectFill (window->RPort
  462.             , knobleft
  463.             , knobtop + knobheight - 2
  464.             , knobleft + knobwidth - 3
  465.             , knobtop + knobheight - 1
  466.             );
  467.  
  468.             SetAPen (window->RPort, hit ? 1 : 2);
  469.  
  470.             /* Draw top border */
  471.             RectFill (window->RPort
  472.             , knobleft
  473.             , knobtop
  474.             , knobleft + knobwidth - 2
  475.             , knobtop + 1
  476.             );
  477.  
  478.             /* Draw left border */
  479.             RectFill (window->RPort
  480.             , knobleft
  481.             , knobtop + 2
  482.             , knobleft + 1
  483.             , knobtop + knobheight - 2
  484.             );
  485.  
  486.             /* Fill edges */
  487.             WritePixel (window->RPort, knobleft + knobwidth - 1, knobtop);
  488.             WritePixel (window->RPort, knobleft, knobtop + knobheight - 1);
  489.         }
  490.         else
  491.         {
  492.             SetAPen (window->RPort, 2);
  493.  
  494.             RectFill (window->RPort
  495.             , knobleft
  496.             , knobtop
  497.             , knobleft + knobwidth - 1
  498.             , knobtop + knobheight - 1
  499.             );
  500.         }
  501.         }
  502.  
  503.         break; }
  504.  
  505.     case GTYP_STRGADGET:
  506.         break;
  507.  
  508.     case GTYP_CUSTOMGADGET:
  509.         break;
  510.  
  511.     } /* switch GadgetType */
  512.     }
  513.  
  514.     SetDrMd (window->RPort, DrawMode);
  515.     SetAPen (window->RPort, apen);
  516.  
  517.     __AROS_FUNC_EXIT
  518. } /* RefreshGList */
  519.